//
//  XLRefreshControl.swift
//  HomeSchoolDemo
//
//  Created by 张晓林 on 16/10/9.
//  Copyright © 2016年 张晓林. All rights reserved.
//

import UIKit
// 临界点
fileprivate let XLRefreshOffset: CGFloat = 60

/// 刷新视图状态
///
/// - nomol:       普通状态(什么都不做)
/// - pulling:     超过临界点，如果放手就开始刷新
/// - willRefresh: 已经超过临界点，并且已经放手，准备开始刷新
enum XLRefreshState {
    case nomol
    case pulling
    case willRefresh
}

class XLRefreshControl: UIControl {
    // 记录父视图
    fileprivate weak var scrollView: UIScrollView?
    // 创建UI属性
    let refreshV = XLRefreshView.refreshV()
    
    init() {
        super.init(frame: CGRect())
        // 设置UI
        setupUI()
    }
    
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        setupUI()
    }
    
    // 获得父类属性
    // 这个方法是在执行addSubview 回调用，移除时也会调用
    override func willMove(toSuperview newSuperview: UIView?) {
        super.willMove(toSuperview: newSuperview)
        // 判断一下
        guard let sv = newSuperview as? UIScrollView else {
            return
        }
        // 记录父视图
        scrollView = sv
        
        // 使用KVO添加父视图属性变化
        // KVC添加监听以后必须在当前视图销毁前移除，否则会直接崩溃
        // 不同于通知，通知不移除时不会发生什么。但是会造成内存泄漏或重复添加
        sv.addObserver(self, forKeyPath: "contentOffset", options: [], context: nil)
        
    }
    
    // 当前视图移除时会调用
    override func removeFromSuperview() {
        // 移除监听.必须在执行父类方法前
        superview?.removeObserver(self, forKeyPath: "contentOffset")
        super.removeFromSuperview()
    }
    
    // KVO的监听回调方法
    override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
        
        guard let sv = scrollView else {
            return
        }
        // 获得高度
        let H = -(sv.contentOffset.y + sv.contentInset.top)
        // 屏蔽向上滚动出屏幕的功能
        if H < 0 {
            return
        }
        
        // 如果是正在拖拽情况下
        if sv.isDragging {
            if H > XLRefreshOffset && refreshV.refreshState == .nomol {
                //
                refreshV.refreshState = .pulling
                // 没放手状态下返回
            }else if H < XLRefreshOffset && refreshV.refreshState == .pulling {
                //
                refreshV.refreshState = .nomol
            }
        }else {
            // 进入这里表示拖拽结束，如果是超过临界点就开始刷新
            if refreshV.refreshState == .pulling {
              
//                beginRefreshing()
                // 发送事件消息
                sendActions(for: .valueChanged)
            }
        }
        
        // 设置控件高度
        self.frame = CGRect(x: 0,
                            y: -H,
                            width: UIScreen.main.bounds.width,
                            height: H)
        
    }
    
    /// 开始刷新
    func beginRefreshing() {
        
        guard let sv = scrollView else {
            return
        }
        
        if refreshV.refreshState == .willRefresh {
            return
        }
        // 已经进入刷新数据状态
        refreshV.refreshState = .willRefresh
        
        // 保持刷新状态
        var inset = sv.contentInset
        inset.top += XLRefreshOffset
        sv.contentInset = inset
    }
    
    /// 结束刷新
    func endRefreshing() {
        guard let sv = scrollView else {
            return
        }
        
        if refreshV.refreshState != .willRefresh {
            return
        }
        
        UIView.animate(withDuration: 0.25, animations: {
            var inset = sv.contentInset
            inset.top -= XLRefreshOffset
            sv.contentInset = inset
            }) { (_) in
                // 修改状态
                self.refreshV.refreshState = .nomol
        }
    }
}

extension XLRefreshControl {
    // 设置UI
    fileprivate func setupUI() {
//        backgroundColor = #colorLiteral(red: 0.9529411793, green: 0.6862745285, blue: 0.1333333403, alpha: 1)
        // 添加视图
        addSubview(refreshV)
        // 裁剪超出边界的内容
//        clipsToBounds = true
        
        // 使用原生的约束框架，必须先关掉系统的自动设置约束的属性
        // storyboard会自动关闭，存代码需手动设置下面这个属性为false
        refreshV.translatesAutoresizingMaskIntoConstraints = false
        // 设置中心X
        addConstraint(NSLayoutConstraint(item: refreshV,
                                         attribute: .centerX,
                                         relatedBy: .equal,
                                         toItem: self,
                                         attribute: .centerX,
                                         multiplier: 1.0,
                                         constant: 0))
        // 设置中心Y
        addConstraint(NSLayoutConstraint(item: refreshV,
                                         attribute: .bottom,
                                         relatedBy: .equal,
                                         toItem: self,
                                         attribute: .bottom,
                                         multiplier: 1.0,
                                         constant: 0))
        // 宽
        addConstraint(NSLayoutConstraint(item: refreshV,
                                         attribute: .width,
                                         relatedBy: .equal,
                                         toItem: nil,
                                         attribute: .notAnAttribute,
                                         multiplier: 1.0,
                                         constant: refreshV.bounds.width))
        // 高
        addConstraint(NSLayoutConstraint(item: refreshV,
                                         attribute: .height,
                                         relatedBy: .equal,
                                         toItem: nil,
                                         attribute: .notAnAttribute,
                                         multiplier: 1.0,
                                         constant: refreshV.bounds.height))
        
    }
}











